﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace Casamiel.API.Infrastructure
{
    /// <summary>
    /// Tag descriptions document filter.
    /// </summary>
    public class TagDescriptionsDocumentFilter : IDocumentFilter
    {
        /// <summary>
        /// Apply the specified swaggerDoc and context.
        /// </summary>
        /// <param name="swaggerDoc">Swagger document.</param>
        /// <param name="context">Context.</param>
        public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
        {
            if (swaggerDoc == null) {
                throw new ArgumentNullException(nameof(swaggerDoc));
            }

            swaggerDoc.Tags = new[] {
                new OpenApiTag{Name="Activity",Description="活动接口"},
                new OpenApiTag{Name="AlipayMiniApp",Description="支付宝小程序接口"},
                new OpenApiTag{Name="ShippingAddress",Description="收货地址接口"},
                new OpenApiTag{Name="Booking",Description="团购卡，预定下单"},
                new OpenApiTag{Name = "Card", Description = "会员卡" },
                new OpenApiTag{Name = "Ele", Description = "饿了么接口" },
                //new Tag{Name="GroupPurchase/Activity", Description="团购活动接口"},
                //new Tag{Name="GroupPurchase/Order", Description="团购接口"},
                new OpenApiTag{Name="ICService",Description="一网服务"},
                new OpenApiTag{Name="Invoice",Description="开票接口"},
                new OpenApiTag{Name="Login",Description="用户登录接口（app）"},
                new OpenApiTag{Name = "Mall", Description = "商城接口" },
                new OpenApiTag{Name = "MeiTuan", Description = "美团接口" },
                new OpenApiTag{Name = "MemberCashCoupon", Description = "代金券接口" },
                new OpenApiTag{Name = "WxApp", Description = "小程序" },
                new OpenApiTag{Name="Open",Description="Open token"},
                new OpenApiTag{Name="Order",Description="订单接口"},
                new OpenApiTag{Name="Product",Description="产品接口"},
                new OpenApiTag{Name="Stock",Description="库存接口"},
                new OpenApiTag{Name="Store",Description="门店接口"},
                new OpenApiTag{Name="StoreService",Description="商店服务接口"},
                new OpenApiTag{Name="Tmall",Description="天猫接口"},
                new OpenApiTag{Name="Staff", Description = "快乐土地-员工卡" }
            };
        }
    }


    /// <summary>
    /// controller添加注释
    /// </summary>
    public class SwaggerControllerDescProvider : ISwaggerProvider
    {
        private readonly ISwaggerProvider _swaggerProvider;
        // private static ConcurrentDictionary<string, SwaggerDocument> _cache = new ConcurrentDictionary<string, SwaggerDocument>();
        private readonly string _xml;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="swaggerProvider"></param>
        /// <param name="xml">xml文档路径</param>
        public SwaggerControllerDescProvider(ISwaggerProvider swaggerProvider, string xml)
        {
            _swaggerProvider = swaggerProvider;
            _xml = xml;
        }

        /// <summary>
        /// 从API文档中读取控制器描述
        /// </summary>
        /// <returns>所有控制器描述</returns>
        public ConcurrentDictionary<string, string> GetControllerDesc()
        {
            string xmlpath = _xml;
            var controllerDescDict = new ConcurrentDictionary<string, string>();
            if (File.Exists(xmlpath))
            {
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load(xmlpath);
                string type, controllerName;

                string[] arrPath;
                int length = -1, cCount = "Controller".Length;
                XmlNode summaryNode;
                foreach (XmlNode node in xmldoc.SelectNodes("//member"))
                {
                    type = node.Attributes["name"].Value;
                    if (type.StartsWith("T:", StringComparison.InvariantCulture))
                    {
                        //控制器
                        arrPath = type.Split('.');
                        length = arrPath.Length;
                        controllerName = arrPath[length - 1];
                        if (controllerName.EndsWith("Controller", StringComparison.InvariantCulture))
                        {
                            //获取控制器注释
                            summaryNode = node.SelectSingleNode("summary");
                            string key = controllerName.Remove(controllerName.Length - cCount, cCount);
                            if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
                            {
                                controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
                            }
                        }
                    }
                }
            }
            return controllerDescDict;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="documentName"></param>
        /// <param name="host"></param>
        /// <param name="basePath"></param>
        /// <returns></returns>
        public OpenApiDocument GetSwagger(string documentName, string host = null, string basePath = null)
        {
            OpenApiDocument srcDoc = _swaggerProvider.GetSwagger(documentName, host, basePath);
            return srcDoc;
        }
    }
}


